package repository

import (
	"fmt"
	"gluenet/modules/manager/server/adapter/repository/helm"
	"gluenet/modules/manager/server/adapter/repository/mysql"
	"gluenet/modules/manager/server/domain/dependency"
	"gluenet/modules/manager/server/domain/entity"
	"gluenet/modules/manager/server/domain/vo"
	"gluenet/modules/manager/server/infra"
	"gluenet/modules/manager/server/infra/prepare"
	"io"
	"time"
)

func init() {
	prepare.RegisterRepo(func() {
		repo := NewConfigRepo()
		prepare.InjectDependency(func() dependency.ConfigMetaRepo {
			return repo
		})
	})
}

type Config struct {
}

func (r *Config) AddCharts(userId string, fileName string, file io.Reader) (*vo.CreateConfigReq, error) {
	info, err := helm.DB.SaveCharts(userId, fileName, file)
	if err != nil {
		return nil, err
	}
	return &vo.CreateConfigReq{
		Name:             info.Name,
		Describe:         info.Describe,
		Version:          info.Version,
		DetailRepoValues: info.Detail,
	}, nil
}

func (r *Config) ImportCharts(repoKey string) ([]*vo.CreateConfigReq, error) {
	//TODO implement me
	panic("implement me")
}

func NewConfigRepo() *Config {
	r := &Config{}
	return r
}

func (r *Config) Get(ID string, userID string) (*entity.Config, error) {
	var obj []entity.Config
	if err := mysql.DB.Where(map[string]interface{}{
		"id":      ID,
		"user_id": userID,
	}).Find(&obj); err != nil {
		return nil, err
	}

	if len(obj) > 1 {
		return nil, fmt.Errorf("much primary keys in sql")
	}

	if len(obj) == 0 {
		return nil, infra.DataNotFind
	}
	//var cfgs = make([]*entity.Config, len(obj))
	//for k, v := range obj {
	//	cfgs[k] = &entity.Config{
	//		Config: v,
	//	}
	//}
	return &obj[0], nil
}

func (r *Config) FindAll() ([]entity.Config, error) {
	var obj []entity.Config
	if err := mysql.DB.Where(map[string]interface{}{}).Find(&obj); err != nil {
		return nil, err
	}
	if len(obj) == 0 {
		return nil, fmt.Errorf("can't find data")
	}
	return obj, nil
}

func (r *Config) FindBy(query map[string]interface{}) ([]entity.Config, error) {
	//TODO implement me
	var obj []entity.Config

	if err := mysql.DB.Where(query).Find(&obj); err != nil {
		return nil, err
	}

	if len(obj) == 0 {
		return nil, fmt.Errorf("can't find data")
	}

	//var cfgs = make([]*entity.Config, len(obj))
	//for k, v := range obj {
	//	cfgs[k] = &entity.Config{
	//		Config: v,
	//	}
	//}
	return obj, nil
}

//func (r *Config) Del(ID string, userId string) (*entity.Config, error) {
//	var cfg entity.Config
//	_, err := mysql.DB.Where(map[string]interface{}{
//		"id":      ID,
//		"user_id": userId,
//	}).Delete(&cfg)
//	if err != nil {
//		return nil, err
//	}
//	return &cfg, nil
//}

func (r *Config) Del(admin bool, userId string, ConfigID string) (*entity.Config, error) {
	condition := map[string]interface{}{
		"id": ConfigID,
	}
	if !admin {
		condition["user_id"] = userId
	}

	var cfg entity.Config
	_, err := mysql.DB.Where(condition).Delete(&cfg)
	if err != nil {
		return nil, err
	}
	return &cfg, nil
}

func (r *Config) Add(req *entity.Config) (*entity.Config, error) {
	req.Created = time.Now()
	req.Updated = time.Now()
	if _, err := mysql.DB.InsertOne(req); err != nil {
		return nil, err
	}
	return req, nil
}

func (r *Config) Update(obj *entity.Config) error {
	//TODO implement me
	panic("implement me")
}
